home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Camelot / Camelot 043 (1989-06)(Swedish User Group of Amiga)(SE)(PD)[WB].zip / Camelot 043 (1989-06)(Swedish User Group of Amiga)(SE)(PD)[WB].adf / zc / md.c < prev    next >
C/C++ Source or Header  |  1989-03-08  |  7KB  |  447 lines

  1. /* Copyright (c) 1988 by Sozobon, Limited.  Author: Johann Ruegg
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  *
  11.  *    md.c
  12.  *
  13.  *    Machine dependant parts of first pass (parse)
  14.  *    Also type checking subroutines.
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include "param.h"
  19. #include "tok.h"
  20. #include "nodes.h"
  21. #include "cookie.h"
  22.  
  23. NODEP bas_type();
  24.  
  25. int adjtab[] = {
  26.     K_INT,        /* none */
  27.     K_SHORT,    /* short */
  28.     K_LONG,     /* long */
  29.     0,        /* short long */
  30.     K_UNSIGNED,    /* unsigned */
  31.     K_UNSIGNED,    /* unsigned short */
  32.     T_ULONG,    /* unsigned long */
  33.     0,        /* unsigned short long */
  34. };
  35.  
  36. adj_type(old, adj)
  37. {
  38.     int rv;
  39.  
  40.     switch (old) {
  41.     case K_CHAR:
  42.         if (adj & SAW_UNS)
  43.             return T_UCHAR;
  44.         break;
  45.     case K_INT:
  46.         rv = adjtab[adj];
  47.         if (rv == 0) {
  48.             error("bad type spec");
  49.             return K_INT;
  50.         }
  51.         return rv;
  52.     case K_FLOAT:
  53.         if (adj & SAW_LONG)
  54.             return K_DOUBLE;
  55.         break;
  56.     }
  57.     return old;
  58. }
  59.  
  60. /* given ICON value, and flags SEE_L,SEE_U
  61.     determine final type */
  62. icon_ty(tp)
  63. NODE *tp;
  64. {
  65.     int flags;
  66.     long val;
  67.     int islong, isuns;
  68.  
  69.     flags = tp->e_flags;
  70.     val = tp->e_ival;
  71.  
  72.     islong = (flags & SEE_L);
  73.     isuns = (flags & SEE_U);
  74.  
  75.     if (islong && isuns)
  76.         return T_ULONG;
  77.     if (islong || islongv(val))
  78.         return K_LONG;
  79.     if (isuns)
  80.         return K_UNSIGNED;
  81.     return isintv((int)val) ? K_INT : K_CHAR;
  82. }
  83.  
  84. isintv(i)
  85. {
  86.     if (i > 0x7f || i < -0x80)
  87.         return 1;
  88.     return 0;
  89. }
  90.  
  91. islongv(l)
  92. long l;
  93. {
  94. #ifndef NOLONGS
  95.     if (l > MAXUNS || l < MININT)
  96.         return 1;
  97. #endif
  98.     return 0;
  99. }
  100.  
  101. mkint(l)
  102. long l;
  103. {
  104.     return l;
  105. }
  106.  
  107. lc_reg(rp, xp)
  108. int *rp;
  109. NODE *xp;
  110. {
  111.     switch (xp->n_tptr->t_token) {
  112.     case STAR:
  113.         return al_areg(rp,xp);
  114.     case K_CHAR:
  115.     case T_UCHAR:
  116.     case T_ULONG:
  117.     case K_INT:
  118.     case K_UNSIGNED:
  119.     case K_LONG:
  120.         return al_dreg(rp,xp);
  121.     default:
  122.         return 0;
  123.     }
  124. }
  125.  
  126. al_areg(rp,xp)
  127. int *rp;
  128. NODEP xp;
  129. {
  130.     register rmask, n;
  131.  
  132.     rmask = *rp;
  133.     for (n=ARV_START; n<=ARV_END; n++)
  134.         if ((rmask & (1<<n)) == 0) {
  135.             xp->e_rno = n;
  136.             *rp |= (1<<n);
  137.             return 1;
  138.         }
  139.     return 0;
  140. }
  141.  
  142. al_dreg(rp,xp)
  143. int *rp;
  144. NODEP xp;
  145. {
  146.     register rmask, n;
  147.  
  148.     rmask = *rp;
  149.     for (n=DRV_START; n<=DRV_END; n++)
  150.         if ((rmask & (1<<n)) == 0) {
  151.             xp->e_rno = n;
  152.             *rp |= (1<<n);
  153.             return 1;
  154.         }
  155.     return 0;
  156. }
  157.  
  158. long
  159. arg_size(sz,np)
  160. long sz;
  161. NODEP np;
  162. {
  163.     np->e_offs = 0;
  164.  
  165.     switch (np->n_tptr->t_token) {
  166.     case '[':
  167.         printf("GAK! array arg ");
  168.         return SIZE_P;
  169.     case K_CHAR:
  170.     case T_UCHAR:
  171.         np->e_offs = SIZE_I - SIZE_C;
  172.         return SIZE_I;
  173. #if SIZE_I != SIZE_S
  174.     case K_SHORT:
  175.         np->e_offs = SIZE_I - SIZE_S;
  176.         return SIZE_I;
  177. #endif
  178.     default:
  179.         return sz;
  180.     }
  181. }
  182.  
  183. mustlval(np)
  184. NODEP np;
  185. {
  186.     switch (np->e_token) {
  187.     case ID:
  188.     case STAR:
  189.     case '.':
  190.         break;
  191.     default:
  192.         errorn("not lvalue", np);
  193.         return 1;
  194.     }
  195.     return 0;
  196. }
  197.  
  198. mustty(np, flags)
  199. NODEP np;
  200. {
  201.     switch (np->n_tptr->t_token) {
  202.     case STAR:
  203.         if (flags & R_POINTER)
  204.             return 0;
  205.         error("pointer not allowed");
  206.         return 1;
  207.     case K_STRUCT:
  208.     case K_UNION:
  209.         if (flags & R_STRUCT)
  210.             return 0;
  211.         error("struct/union not allowed");
  212.         return 1;
  213.     case K_CHAR:
  214.     case K_SHORT:
  215.     case K_INT:
  216.     case K_UNSIGNED:
  217.     case K_LONG:
  218.     case T_UCHAR:
  219.     case T_ULONG:
  220.         if (flags & R_INTEGRAL)
  221.             return 0;
  222.         error("integral not allowed");
  223.         return 1;
  224.     case K_FLOAT:
  225.     case K_DOUBLE:
  226.         if (flags & R_FLOATING)
  227.             return 0;
  228.         error("floating not allowed");
  229.         return 1;
  230.     default:
  231.         error("bad type");
  232.         return 1;
  233.     }
  234.     return 0;
  235. }
  236.  
  237. NODEP
  238. functy(np)
  239. NODEP np;
  240. {
  241.     int lt;
  242.  
  243.     lt = np->n_tptr->t_token;
  244.     if (lt != K_VOID)
  245.         mustty(np, R_ASSN);
  246.     switch (lt) {
  247.     case STAR:
  248.     case K_STRUCT:
  249.     case K_UNION:
  250.         return np->n_tptr;
  251.     }
  252.     lt = widen(lt);
  253.     return bas_type(lt);
  254. }
  255.  
  256. NODEP
  257. normalty(lp, rp)
  258. NODEP lp, rp;
  259. {
  260.     /* already checked types are R_ARITH */
  261.     /* rp may be NULL */
  262.     int lt, rt, rett;
  263.  
  264.     lt = lp->n_tptr->t_token;
  265.     if (rp)
  266.         rt = rp->n_tptr->t_token;
  267.     else
  268.         rt = K_INT;
  269.     rett = maxt(widen(lt), widen(rt));
  270.     return bas_type(rett);
  271. }
  272.  
  273. asn_chk(ltp, rp)
  274. NODEP ltp, rp;
  275. {
  276.  
  277.     switch (ltp->t_token) {
  278.     case K_STRUCT:
  279.     case K_UNION:
  280.         if (same_type(ltp, rp->n_tptr) == 0)
  281.             error("bad struct assign");
  282.         return;
  283.     case STAR:
  284.         if (mayzero(rp))
  285.             return;
  286.         if (mustty(rp, R_POINTER))
  287.             return;
  288.         if (same_type(ltp->n_tptr, rp->n_tptr->n_tptr)
  289.             == 0)
  290.             warn("pointer types mismatch");
  291.         return;
  292.     default:
  293.         if (mustty(rp, R_ARITH))
  294.             return;
  295.     }
  296. }
  297.  
  298. chkcmp(np)
  299. NODEP np;
  300. {
  301.     /* already checked types are R_SCALAR */
  302.     int lt, rt;
  303.     NODEP lp = np->n_left, rp = np->n_right;
  304.  
  305.     lt = lp->n_tptr->t_token;
  306.     lt = (lt == STAR);
  307.     rt = rp->n_tptr->t_token;
  308.     rt = (rt == STAR);
  309.     if (lt && rt) {         /* ptr cmp ptr */
  310.         if (same_type(lp->n_tptr, rp->n_tptr) == 0) {
  311.             warn("cmp of diff ptrs");
  312.         }
  313.     } else if (lt) {        /* ptr cmp intg */
  314.         mustzero(rp);
  315.     } else if (rt) {        /* intg +-[ ptr */
  316.         mustzero(lp);
  317.     } /* else both ARITH */
  318. }
  319.  
  320. NODEP
  321. colonty(np)
  322. NODEP np;
  323. {
  324.     /* already checked types are R_SCALAR */
  325.     int lt, rt;
  326.     NODEP lp = np->n_left, rp = np->n_right;
  327.  
  328.     lt = lp->n_tptr->t_token;
  329.     lt = (lt == STAR);
  330.     rt = rp->n_tptr->t_token;
  331.     rt = (rt == STAR);
  332.     if (lt && rt) {         /* ptr : ptr */
  333.         warn(": diff ptrs");
  334.         return lp->n_tptr;
  335.     } else if (lt) {        /* ptr : intg */
  336.         mustzero(rp);
  337.         return lp->n_tptr;
  338.     } else if (rt) {
  339.         mustzero(lp);
  340.         return rp->n_tptr;
  341.     } else
  342.         return normalty(lp, rp);
  343. }
  344.  
  345. NODEP
  346. addty(np)
  347. NODEP np;
  348. {
  349.     /* already checked types are R_SCALAR */
  350.     /* op is '+' or '-' or '+=' or '-=' or '[' */
  351.     int oop = np->e_token;
  352.     int op;
  353.     int lt, rt;
  354.     NODEP lp = np->n_left, rp = np->n_right;
  355.  
  356.     op = oop;
  357.     if (isassign(op))
  358.         op -= ASSIGN 0;
  359.     lt = lp->n_tptr->t_token;
  360.     lt = (lt == STAR);
  361.     rt = rp->n_tptr->t_token;
  362.     rt = (rt == STAR);
  363.     if (lt && rt) {         /* ptr - ptr */
  364.         if (oop != '-' || same_type(lp->n_tptr, rp->n_tptr) == 0) {
  365.             error("bad +/-");
  366.             return lp->n_tptr;
  367.         }
  368.         np->e_token = PTRDIFF;
  369.         np->e_offs = lp->n_tptr->n_tptr->t_size;
  370.         return bas_type(K_INT);
  371.     } else if (lt) {        /* ptr +-[ intg */
  372. pandi:
  373.         mustty(rp, R_INTEGRAL);
  374.         np->e_offs = lp->n_tptr->n_tptr->t_size;
  375.         if (op == '+')
  376.             np->e_token += PTRADD-'+';
  377.         else if (op == '-')
  378.             np->e_token += PTRSUB-'-';
  379.         return lp->n_tptr;
  380.     } else if (rt) {        /* intg +-[ ptr */
  381.         if (isassign(oop) || op == '-') {
  382.             error("illegal int op ptr");
  383.             return bas_type(K_INT);
  384.         }
  385.         /* switch sides so intg is on right */
  386.         np->n_left = rp;
  387.         np->n_right = lp;
  388.         lp = rp;
  389.         rp = np->n_right;
  390.         goto pandi;
  391.     } else {        /* intg +- intg */
  392.         return normalty(lp, rp);
  393.     }
  394. }
  395.  
  396. mustzero(np)
  397. NODEP np;
  398. {
  399.     if (np->e_token == ICON && np->e_ival == 0) {
  400.         return;
  401.     }
  402.     error("bad ':' combination");
  403. }
  404.  
  405. mayzero(np)
  406. NODEP np;
  407. {
  408.     if (np->e_token == ICON && np->e_ival == 0) {
  409.         return 1;
  410.     }
  411.     return 0;
  412. }
  413.  
  414. widen(ty)
  415. {
  416.     switch (ty) {
  417.     case K_CHAR:
  418.     case T_UCHAR:
  419.         return K_INT;
  420.     case K_SHORT:
  421.         return K_INT;
  422.     case K_FLOAT:
  423.         return K_DOUBLE;
  424.     default:
  425.         return ty;
  426.     }
  427. }
  428.  
  429. int pri_t[] = {
  430.     1, 6,        /* uchar, ulong */
  431.     5,2,4,3,0,    /* long, short, uns, int, char */
  432.     7,8,9        /* float, double, void */
  433. };
  434.  
  435.  
  436. extern nmerrors;
  437.  
  438. maxt(t1, t2)
  439. {
  440.  
  441.     if (nmerrors)
  442.         return K_INT;
  443.     if (pri_t[t1-FIRST_BAS] > pri_t[t2-FIRST_BAS])
  444.         return t1;
  445.     return t2;
  446. }
  447.